package com.${artifactId}.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fow.core.platform.runtime.RuntimeEnvironment;
import com.fow.core.platform.runtime.RuntimeSettings;
import com.fow.core.platform.sms.SMSService;
import com.fow.core.platform.sms.impl.YiChiSMSServiceImpl;
import org.apache.commons.dbcp.BasicDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Controller;

import javax.sql.DataSource;

/**
 * Created by Greg.Chen on 2015/5/27.
 */
@Configuration
@ComponentScan(basePackages = {"com.${artifactId}","com.fow.core.util"
        ,"com.fow.core.platform.web.rest"
		}, excludeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, value = { Controller.class }) })
@EnableAspectJAutoProxy(proxyTargetClass=true)
@PropertySource({
        "classpath:conf/${runtime.env}/jdbc.properties",
        "classpath:conf/${runtime.env}/settings.properties"
})
@EnableScheduling
@EnableAsync
public class AppConfig {

    private static final Logger logger = LoggerFactory.getLogger(AppConfig.class);

    @Autowired
    private Environment env;


    @Bean(name = "dataSource")
    public DataSource dataSourceBean() {

        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
        dataSource.setUrl(env.getProperty("jdbc.url"));
        dataSource.setUsername(env.getProperty("jdbc.username"));
        dataSource.setPassword(env.getProperty("jdbc.password"));
        dataSource.setMinIdle(Integer.parseInt(env.getProperty("jdbc.minIdle")));
        dataSource.setMaxIdle(Integer.parseInt(env.getProperty("jdbc.maxIdle")));
        dataSource.setMaxWait(Integer.parseInt(env.getProperty("jdbc.maxWait")));
        dataSource.setMaxActive(Integer.parseInt(env.getProperty("jdbc.maxActive")));
        dataSource.setInitialSize(Integer.parseInt(env.getProperty("jdbc.initialSize")));
        dataSource.setTestOnBorrow(true);
        dataSource.setTestWhileIdle(true);
        dataSource.setValidationQuery("select 1");
        return dataSource;
    }

    @Bean(name = "transactionManager")
    public DataSourceTransactionManager hibernateTransactionManager() {

        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSourceBean());
        return dataSourceTransactionManager;
    }

    @Bean(name = "sessionFactory")
    public SqlSessionFactoryBean sqlSessionFactoryBean() {

        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSourceBean());
        sessionFactory.setConfigLocation(new ClassPathResource("sqlMapConfig.xml"));

        return sessionFactory;

    }

    @Bean(name = "sqlSession")
    @Scope("prototype")
    public SqlSessionTemplate SqlSessionTemplateBean() throws Exception {

        SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactoryBean().getObject());
        return sqlSessionTemplate;

    }

    @Bean(name = "runTimeSetting")
    public RuntimeSettings RuntimeSettingsBean(){
        RuntimeSettings runtimeSettings = new RuntimeSettings();
        runtimeSettings.setEnvironment(RuntimeEnvironment.valueOf(env.getProperty("runtime.env").toUpperCase()));
        return runtimeSettings;
    }

    @Bean(name = "messageSource")
    public ResourceBundleMessageSource ResourceBundleMessageSourceBean(){
        ResourceBundleMessageSource resourceBundleMessageSource = new ResourceBundleMessageSource();
        resourceBundleMessageSource.setBasenames("message/admin-exceptions", "message/exceptions");

        return resourceBundleMessageSource;
    }

    @Bean(name = "objectMapper")
    public ObjectMapper ObjectMapperBean(){
        return new ObjectMapper();
    }
}
